package com.lw.common.base

import android.os.Bundle
import android.view.LayoutInflater
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.kongzue.dialogx.dialogs.WaitDialog
import com.lw.common.manager.ActivityManager
import com.lw.common.network.request.IUiView
import com.lw.common.utils.EventUtils
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

/**
 * Activity基类
 */
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity(), IUiView {

    protected lateinit var mBinding: VB

    @LayoutRes
    protected open val layoutId = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityManager.getInstance().addActivity(this)
        if (isRegisterEvent) {
            EventUtils.register(this)
        }
        initViewDataBinding()
        initView(savedInstanceState)
        initObserve()
        initData()
        initListener()
    }

    abstract fun initView(savedInstanceState: Bundle?)

    open fun initObserve() {}

    open fun initData() {}

    open fun initListener() {}

    open val isRegisterEvent = false

    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleEvent(event)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    open fun onStickyEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleStickyEvent(event)
        }
    }

    open fun handleEvent(event: BaseEvent) {}

    open fun handleStickyEvent(event: BaseEvent) {}

    /**
     * DataBinding or ViewBinding
     */
    private fun initViewDataBinding() {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments
                .map { it as Class<*> }
                .first { ViewBinding::class.java.isAssignableFrom(it) }
            when {

                ViewBinding::class.java.isAssignableFrom(cls) && cls != ViewBinding::class.java -> {
                    cls.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                        @Suppress("UNCHECKED_CAST")
                        mBinding = it.invoke(null, layoutInflater) as VB
                        setContentView(mBinding.root)
                    }
                }

                else -> {
                    if (layoutId == 0) throw IllegalArgumentException("If you don't use ViewBinding, you need to override method layoutId")
                    setContentView(layoutId)
                }
            }
        } else throw IllegalArgumentException("Generic error")
    }

    override fun showLoading(loadingText: String) {
        WaitDialog.show(loadingText)
    }

    override fun dismissLoading() {
        WaitDialog.dismiss()
    }

    override fun onDestroy() {
        super.onDestroy()
        if (isRegisterEvent) {
            EventUtils.unregister(this)
        }
        ActivityManager.getInstance().removeActivity(this)
    }

}